package com.atguigu.crowd.mvc.config;

import com.atguigu.crowd.exception.DeleteFailedException;
import com.atguigu.crowd.exception.LoginAcctAlreadyInUserException;
import com.atguigu.crowd.exception.LoginAcctAlreadyInUserForUpdateException;
import com.atguigu.crowd.constant.CrowdConstan;
import com.atguigu.crowd.util.CrowdUtil;
import com.atguigu.crowd.util.ResultEntity;
import com.google.gson.Gson;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author zzqstart
 * @Description
 * @date 2022-08-29 1:40
 */
@ControllerAdvice
public class CrowdExceptionResolve {

    @ExceptionHandler(LoginAcctAlreadyInUserForUpdateException.class)
    public ModelAndView resolveDuplicateKeyException(LoginAcctAlreadyInUserForUpdateException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolve(viewName, exception, request, response);
    }

    @ExceptionHandler(LoginAcctAlreadyInUserException.class)
    public ModelAndView resolveDuplicateKeyException(LoginAcctAlreadyInUserException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "admin-add";
        return commonResolve(viewName, exception, request, response);
    }

    @ExceptionHandler(DeleteFailedException.class)
    public ModelAndView resolveNullPointerException(DeleteFailedException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "forward:/admin/page.html";
        return commonResolve(viewName, exception, request, response);
    }

    @ExceptionHandler(Exception.class)
    public ModelAndView Exception(Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "system-error";
        return commonResolve(viewName, exception, request, response);
    }

    private ModelAndView commonResolve(String viewName, Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1、判断当前请求类型
        boolean judegResult = CrowdUtil.judgeRequestType(request);
        //2、如果是ajax请求
        if (judegResult) {
            //3、创建resultEntity对象
            ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());
            //4、创建Gson对象
            Gson gson = new Gson();
            //5、将ResultEntity对象转换为JSON字符集
            String json = gson.toJson(resultEntity);
            //6、将Json字符串作为响应体返回给浏览器
            response.getWriter().write(json);
            //7、由于上面已经通过原生的response对象返回了响应，所以不提供mv对象
            return null;
        }

        //8、如果不是AJax请求则创建mv对象
        ModelAndView modelAndView = new ModelAndView();
        //9、将ex对象存入模型
        modelAndView.addObject(CrowdConstan.ATTR_NAME_EXCEPTION, exception);
        //10、设置对应视图名称
        modelAndView.setViewName(viewName);
        return modelAndView;
    }


    //    第一代
//    @ExceptionHandler(NullPointerException.class)
    public ModelAndView resolveNullPointerExceptionNO1(Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1、判断当前请求类型
        boolean judegResult = CrowdUtil.judgeRequestType(request);
        //2、如果是ajax请求
        if (judegResult) {
            //3、创建resultEntity对象
            ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());
            //4、创建Gson对象
            Gson gson = new Gson();
            //5、将ResultEntity对象转换为JSON字符集
            String json = gson.toJson(resultEntity);
            //6、将Json字符串作为响应体返回给浏览器
            response.getWriter().write(json);
            //7、由于上面已经通过原生的response对象返回了响应，所以不提供mv对象
            return null;
        }

        //8、如果不是AJax请求则创建mv对象
        ModelAndView modelAndView = new ModelAndView();
        //9、将ex对象存入模型
        modelAndView.addObject("exception", exception);
        //10、设置对应视图名称
        modelAndView.setViewName("system-error");
        //11、返回mv对象
        return modelAndView;
    }
}
